package com.bjpowernode.money.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.bjpowernode.money.mapper.FinanceAccountMapper;
import com.bjpowernode.money.mapper.RechargeRecordMapper;
import com.bjpowernode.money.model.RechargeRecord;
import com.bjpowernode.money.service.RechargeRecordService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;

/**
 * @author ZHAOZHENYU
 * @since 2022/10/27
 */
@Service(interfaceClass = RechargeRecordService.class,version = "1.0.0",timeout = 20000)
@Component
public class RechargeRecordServiceImpl implements RechargeRecordService {

    @Autowired
    private RechargeRecordMapper rechargeRecordMapper;

    @Autowired
    private FinanceAccountMapper financeAccountMapper;

    @Override
    @Transactional
    public int recharge(RechargeRecord rechargeRecord) {
        return rechargeRecordMapper.insertSelective(rechargeRecord);
    }

    @Override
    @Transactional
    public int rechargeFail(String out_trade_no) {
        return rechargeRecordMapper.updateFailStatusByRechargeNo(out_trade_no);
    }

    @Override
    @Transactional
    public int rechargeSuccess(String out_trade_no, Double rechargeMoney, Integer userId) {
        if (!ObjectUtils.allNotNull(userId)){
            // 如果登录用户过期 用户信息为空 重新查出
            userId = rechargeRecordMapper.selectUidByRechargeNo(out_trade_no);
        }
        // 更新支付状态为 1
        // 定时器可能先改了，只有状态为0时才更新，否则手动回滚
        int num = rechargeRecordMapper.updateSuccessStatusByRechargeNo(out_trade_no);
        if (num == 0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return num;
        }
        // 增加用户余额
        // 追加乐观锁，防止充值两次
        int version = financeAccountMapper.selectVersionByUid(userId);
        num = financeAccountMapper.updateAvailableMoneyForRecharge(userId, rechargeMoney,version);
        if (num == 0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return num;
        }
        return num;
    }

    @Override
    public List<RechargeRecord> queryByStatus() {
        return rechargeRecordMapper.selectByStatus();
    }

    @Override
    public RechargeRecord queryById(Integer id) {
        return rechargeRecordMapper.selectByPrimaryKey(id);
    }

}
